
#ifndef MSGUTILS_BIT_WRITER_INL_H
#define MSGUTILS_BIT_WRITER_INL_H

#include <type_traits>

template<class T, bool is_arithmetic>
struct WriteDispatch {
  static void Write(BitWriter& writer, const T& val) { val->Write(writer); }
};

template<class T>
struct WriteDispatch<T, true> {
  static void Write(BitWriter& writer, const T& val) { 
    writer.EncodeNumber(sizeof(T) * 8, &val); 
  }
};

template<size_t size>
BitWriter::BitWriter(uint8_t (&buffer)[size]) 
    : wbuf_(NULL),
      delete_wbuf_(false) {
  Construct(buffer, size);
}

template<class T>
BitWriter& BitWriter::operator<<(const T& val) {
  Write(val);
  return *this;
}

template<class T>
void BitWriter::Write(const T& val) {
  WriteDispatch<T, std::is_arithmetic<T>::value>::Write(*this, val);
}

template<class T>
void BitWriter::AddBlock(const T* block, size_t size) {
  Write(size);
  for (size_t i = 0; i < size; ++i) 
    Write(block[i]);
}

template<class T, size_t size>
void BitWriter::Write(const T (&array)[size]) {
  AddBlock(array, size);
}

#endif // MSGUTILS_BIT_WRITER_INL_H 

